package genstream.http

import javax.servlet.http.HttpServletRequest
import genstream._
import org.apache.commons.fileupload.servlet.{ServletRequestContext, ServletFileUpload}
import org.apache.commons.fileupload.{FileItemIterator, FileUpload}
import scaladuct.{Ref, Starter}
import javax.validation.constraints.NotNull

/**
 * Created by IntelliJ IDEA.
 * User: zslajchrt
 * Date: 16.4.11
 * Time: 12:59
 * To change this template use File | Settings | File Templates.
 */

class HttpRequestResource(request: HttpServletRequest) extends InputResource {

  def openSinglePartIterator: InputStreamIterator =
    new ListStreamIterator(List(new DefaultInputStreamHolder(request.getInputStream)))

  def openMultiPartIterator: InputStreamIterator = {
    val upload = new FileUpload()
    new HttpRequestStreamIterator(upload.getItemIterator(new ServletRequestContext(request)))
  }

  def openIterator(context: StreamingContext) = {

    val isMultipart = ServletFileUpload.isMultipartContent(request)

    if (isMultipart) {
      openMultiPartIterator
    } else {
      openSinglePartIterator
    }

  }

}

class HttpRequestStreamIterator(itemsIterator: FileItemIterator) extends InputStreamIterator {

  def next() = {
    if (!itemsIterator.hasNext) {
      null
    } else {
      val item = itemsIterator.next()

      if (!item.isFormField()) {
        val fileName = item.getName()
        val inputStream = item.openStream
        new DefaultInputStreamHolder(inputStream)
      } else
        next
    }
  }

  def close() = null

}

@serializable
@SerialVersionUID(1L)
class HttpRequestResourceStarterCookie {
  @Ref(name = "?") @NotNull
  var requestGetter: () => HttpServletRequest = null
}

@SerialVersionUID(1L)
class HttpRequestResourceStarter extends Starter[ServiceFactory[HttpRequestResource]] {

  def newInstance(): ServiceFactory[HttpRequestResource] = phaseGetRequest(new HttpRequestResourceStarterCookie)

  def phaseGetRequest(cookie: HttpRequestResourceStarterCookie) =
    new FunctionalServiceFactory(new HttpRequestResource(cookie.requestGetter()))

  def destroy(instance: ServiceFactory[HttpRequestResource]) = null

}
